单文件上传
原理
- 文件从用户本地电脑通过web表单传输到服务器指定目录下
 
流程
- 浏览器请求一个服务器html脚本,包含文件上传表单
 
- 用户选择文件并上传
 
- 服务器将文件保存到临时目录
 
- 服务器脚本开始工作,判断文件有效,将有效文件从tmp目录移到指定目录(文件上传完成)
 
[zd-plane title=“演示图”]

[/zd-plane]
表单制作
表单包含三个属性:
- method属性:表单必须用post方式
 
- enctype属性:form 表单属性,用来规范表单数据的编码方式
 
- action属性:将数据提交给哪里
 
对应的HTML代码
1 2 3 4
   | <form method='post' enctype='multipart/form-data' action='action.php'> <input type="file" name="image"> <input type="submit" name="submit" value="提交"> </form>
   | 
 
用户看到上传文件和提交按钮,用户提交后,文件上传到服务器临时文件夹
$_FILES值
超预变量**$_FILES,**用来存储用户上传的文件信息
$_FILES包含以下内容
name :
tmp_name:
type:
- 显示文件类型(不能相信name的后缀!!!!!!)
 
error:
文件上传的代号告知php文件接收中出现的问题
- 0 上传成功
 
- 1 文件超过了php设置的最大值
 
- 2 文件超过html表单最大值
 
- 3 只有部分文件被上传,出现网络中断
 
- 4 没有文件被上传
 
- 6 找不到临时文件
 
- 7 php没有权限将临时文件移动到指定目录
 
size:
知道_FILES功能后,创建‘file=$_FILES[‘image’]` ;获得文件全部信息。使用
$file['tmp_name'] 将得到文件名xxx.jpg
$file['type'] 文件类型
等等函数来移动文件到目标目录
移动临时文件到目标位置
- 判断是否为http上传的文件 
is_uploaded_file($filename) 
- 如果满足条件1则移动文件 
move_uploaded_file($filename,$destination) 
1 2 3 4 5 6 7 8 9
   | #创建file变量,取得文件 $file=$_FILES['image']; #这里的名字与表单内input 的file类型的 name一样 #判断是否为上传文件 if(is_uploaded_file($file['tmp_name'])){  #将文件移动到新位置,获得文件名字$file['name']; move_uploaded_file($file['tmp_name'],'diretory'.'/'.$file['name']); }else{ echo '不是上传文件'; }
   | 
 
以上为单文件上传过程
多文件上传
html代码
同名表单
所有上传的文件属于一个数组
1 2 3 4
   | html代码 <input type="file" name="image[]" /> <input type="file" name="image[]" /> <input type="file" name="image[]" />
   | 
 
则$_FILES中,会包含一个image的数组,里面是name属性和type属性等等 每个属性又包含三个值,分别对应三个文件
[zd-plane title=“结果图片”]

[/zd-plane]
不同名表单
文件有各自的名字,不属于一个数组
1 2 3 4
   | html代码 <input type="file" name="head" /> <input type="file" name="body" /> <input type="file" name="footer" />
   | 
 
则$_FILES 将包含 三个类分别为head\body\footer,各自包含自己的name,type等属性。
[zd-plane title=“结果图片”]

[/zd-plane]
多文件遍历
不同名表单遍历
1 2 3 4 5 6 7 8 9 10
   | 按表单名字直接遍历 foreach ($_FILES as $file){ if(is_uploaded_file($file['tmp_name'])){ if(move_uploaded_file($file['tmp_name'],'./post_files/'.$file['name'])){ echo '上传成功'; }else{ echo '上传失败'; } } }
   | 
 
同名表单遍历
1 2 3 4 5 6 7 8 9 10 11 12
   | 因为name\tepe里面各自包含多个变量,那就直接按索引遍历 for ($i = 0; $i < 3; $i++) { // code... $files=$_FILES['image']; if(is_uploaded_file($files['tmp_name'][$i])){ if(move_uploaded_file($files['tmp_name'][$i],'./post_files/'.$files['name'][$i])){ echo '上传成功'; }else{ echo '上传失败'; } } }
   | 
 
文件上传的整完代码
[zd-plane title=“文件上传函数”]
upload_single_file函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
   | <?php #将上传文件封装成函数 function upload_single_file($file,$allow_type,$path,&$error,$allow_format=[],$max_size=2000000){     if(is_array($file)&&isset($file['error'])){          #判断文件error是否有值     }else{         $error ='文件无效';         return false;     }      // 3、判断保存路径是否有效     if(!is_dir($path)){         $error='路径无效';         return false;     }
  // 4、判断文件本身是否有错     switch($file['error']){         case 1:         case 2:             $error='文件超出服务器允许大小';             return false;         case 3:             $error='文件上传过程出现错误';             return false;         case 4:             $error='未选择要上传的文件';             return false;         case 6:         case 7:             $error='文件保存失败';             return false;     }      // 5、判断MIME类型是否允许     if(!in_array($file['type'],$allow_type)){         $error='文件类型不合适';         return false;     }      // 6、判断文件是否过大     if($file['size']>$max_size){         $error='文件过大';         return false;     }          // 7、判断后缀是否允许     $ext=ltrim(strrchr($file['name'],'.'),'.');     if(!empty($allow_format) && !in_array($ext,$allow_format)){         $error='文件后缀不符合!!!只能为jpg,jpeg,png,gif';         return false;     }      // 8、移到指定目录          if(!is_uploaded_file($file['tmp_name'])){         $error='不是上传文件';         return false;     }          // 判断文件是否已经存在     $file_path=$path.'/'.$file['name'];     if(file_exists($file_path)){         $error='文件已经存在';         return false;     }          if(move_uploaded_file($file['tmp_name'],$path.'/'.$file['name'])){         // 检测文件是否有毒         if(check_hex($path,$file['name'])==5){             unlink($path.'/'.$file['name']);             $error='文件可能包含病毒,上传失败';             return false;         }else{             return true;             // return $file['name'];         }
      }else{         $error='文件上传失败';         return false;     }           }
      $file=$_FILES['image'];     $path='./post_files';     $allow_type=['image/jpg','image/jpeg','image/png','image/gif'];     $allow_format=['jpg','jpeg','png','gif'];     $max_size=20000000;
      require './check_hex.php';
           if(upload_single_file($file,$allow_type,$path,$error,$allow_format,$max_size)){         // echo $file_name;         echo '上传成功';     }else{         echo $error;     }
   | 
 
check_hex函数,检测图片是否包含一般病毒
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
   | <?php header("Content-type: text/html; charset=utf-8"); function check_hex($path,$img) {     $status = 0;     $tips = array(         "0" => "文件没问题",         "5" => "文件有毒",         "-1" => "文件没有上传"     );     echo '<br/>';     $img=$path.'/'.$img;     if (file_exists($img)) {         $resource = fopen($img, 'rb');         $fileSize = filesize($img);         fseek($resource, 0);         if ($fileSize > 512) { // 取头和尾             $hexCode = bin2hex(fread($resource, 512));             fseek($resource, $fileSize - 512);             $hexCode .= bin2hex(fread($resource, 512));         } else { // 取全部             $hexCode = bin2hex(fread($resource, $fileSize));         }         fclose($resource);         /* 匹配16进制中的 <% ( ) %> */         /* 匹配16进制中的 <? ( ) ?> */         /* 匹配16进制中的 <script | /script> 大小写亦可 */         if (preg_match("/(3c25.*?28.*?29.*?253e)|(3c3f.*?28.*?29.*?3f3e)|(3C534352495054)|(2F5343524950543E)|(3C736372697074)|(2F7363726970743E)/is", $hexCode)) {             $status = 5;         }     } else {         $status = -1;     }     return $status; }
 
 
 
 
 
   | 
 
[/zd-plane]